package Accessors;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Locale;

import org.json.JSONException;
import org.json.JSONObject;

import utils.RESTfulConnect;
import utils.URLTools;

import Callbacks.AbstractCallback;
import Enums.RFAT;
import Models.Allocation;
import Models.AllocationTemplate;
import Models.InsertedAllocations;
import Presenter.AllocationPresenter;
import Presenter.AllocationTemplatePresenter;
import Presenter.InsertedAllocationsPresenter;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;

@SuppressWarnings("rawtypes")
public class AllocationAccessor extends AbstractAccessor<Allocation,AllocationPresenter,AbstractCallback> {
	private final String NAME = "allocation";
	private final String DIALOG = "Allocation";
	
	private final static AllocationPresenter presenter = new AllocationPresenter();
	private AbstractCallback callback = null;

	SimpleDateFormat timeFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZZZ", Locale.US);
	
	//Modal dialog variable.
	ProgressDialog modalDialog = null;
	
	public AllocationAccessor(AbstractCallback callback){
		super(presenter, callback);
		this.callback = callback;
	}
	
	//Public access functions.
	public void getAllItems(final Context context){
		String dialog = "Loading " + DIALOG + " List...";
		String rfString = NAME;
		super.getAllItems(context, dialog, rfString);
	}

	public void getAllOpenAllocations(final Context context){
		String dialog = "Loading " + DIALOG + " List...";
		String rfString = NAME + "/runNamedQuery/Allocation.findOpenAllocations";
		super.getAllItems(context, dialog, rfString);
	}
	
	public void getItem(final int id, final Context context){
		String dialog = "Loading " + DIALOG + "...";
		String rfString = NAME + "/" + Integer.toString(id);
		super.getItem(context, dialog, rfString);
	}
	
	public void doItemUpdate(final Allocation item, final Context context){
		String dialog = "Updating " + DIALOG + "...";
		String rfString = NAME;
		super.doItemUpdate(item, context, dialog, rfString);
	}
	
	public void doItemInsert(final Allocation item, final Context context){
		String dialog = "Inserting " + DIALOG + "...";
		String rfString = NAME;
		super.doItemInsert(item, context, dialog, rfString);
	}
	
	/*************************************************************
	 * Call to insert allocation(s) based on template and return inserted items.
	 *************************************************************/
	public void createAllocationFromTemplate(final Context context, final int templateID, final Date dueDate){
		String dialog = "Loading " + DIALOG + " List...";
		String rfString = NAME + "/insertAllocationFromTemplate/" + Integer.toString(templateID) + "/" + dueDate.toString();
		rfString = rfString.replaceAll(" ", "%20");
		getInsertedAllocationsItem(context, dialog, rfString);
	}
	
	public void getInsertedAllocationsItem(final Context context, final String dialog, final String str){
		modalDialog = ProgressDialog.show(context, null, dialog);
		final String strStart = URLTools.getURLString(context);
		new DownloadInsertedAllocationsItemTask().execute(strStart+str, URLTools.getUSERString(context), URLTools.getPASSString(context));
	}
	
	private class DownloadInsertedAllocationsItemTask extends AsyncTask<String, Void, String> {
    	@Override
        protected String doInBackground(String... urls) {

            try {
                return RESTfulConnect.getResource(urls[0], urls[1], urls[2]);
            } catch (IOException e) {
            	e.printStackTrace();
            	return "Connection Error";
            }
        }
    	@SuppressWarnings("unchecked")
		@Override
        protected void onPostExecute(String result) {
    		InsertedAllocationsPresenter iaPresenter = new InsertedAllocationsPresenter();
    		InsertedAllocations item = iaPresenter.tryJSONParse(result);
    		modalDialog.dismiss();
    		ArrayList<InsertedAllocations> items = new ArrayList<InsertedAllocations>();
    		callback.callback(item, RFAT.GET_SINGLE, items);
        }
    }
	
	/*************************************************************
	 * Code to handle deletion of items.
	 *************************************************************/
	public void deleteAllSimilarAllocationsAfterDate(final Allocation item, final Date date, final Context context){
		String dialog = "Loading " + DIALOG + " List...";
		String rfString = NAME + "/removeAllSimilarAfterDate/" + Integer.toString(item.getTemplateID()) + "/" + date.toString();
		rfString = rfString.replaceAll(" ", "%20");
		super.deleteItem(context, dialog, rfString);
	}
	
	public void deleteItem(final Allocation item, final Context context){
		String dialog = "Loading " + DIALOG + " List...";
		String rfString = NAME + "/" + Integer.toString(item.getAllocationID());
		super.deleteItem(context, dialog, rfString);
	}
	
	/*************************************************************
	 * Code to set allocation to complete.
	 *************************************************************/
	public void setAllocationCompleteAndUpdateAllocations(final Allocation item, final Context context){
		String dialog = "Updating " + DIALOG + "...";
		String rfString = NAME + "/setAllocationCompleteAndUpdateAllocations";
		super.doItemUpdate(item, context, dialog, rfString);
	}
	
	/*************************************************************
	 * Code to update all allocations with same template index.
	 *************************************************************/
	public void updateAllSimilarAllocations(final Allocation item, final int days, final Context context){
		String dialog = "Updating " + DIALOG + "...";
		String rfString = NAME + "/updateAllSimilarItems/" + Integer.toString(days);
		doSimilarUpdate(item, context, dialog, rfString);
	}
	
	public void doSimilarUpdate(final Allocation item, final Context context, final String dialog, final String str){
		modalDialog = ProgressDialog.show(context, null, dialog);
		final String strStart = URLTools.getURLString(context);
		new UpdateSimilarItemTask().execute(strStart+str, URLTools.getUSERString(context), URLTools.getPASSString(context), presenter.createJSON(item).toString());
	}
	
	private class UpdateSimilarItemTask extends AsyncTask<String, Void, String> {
    	@Override
        protected String doInBackground(String... urls) {
            try {
                return RESTfulConnect.putResource(urls[0], urls[1], urls[2], urls[3]);
            } catch (IOException e) {
            	e.printStackTrace();
            	return "Connection Error";
            }
        }
    	@SuppressWarnings("unchecked")
		@Override
        protected void onPostExecute(String result) {
    		InsertedAllocationsPresenter iaPresenter = new InsertedAllocationsPresenter();
    		InsertedAllocations item = iaPresenter.tryJSONParse(result);
    		modalDialog.dismiss();
    		ArrayList<InsertedAllocations> items = new ArrayList<InsertedAllocations>();
    		callback.callback(item, RFAT.UPDATE, items);
        }
    }
	
	/*************************************************************
	 * Code create a new PSO from allocation.
	 *************************************************************/
	public void createPSOfromAllocation(final Allocation item, final int custID, final Context context){
		String dialog = "Updating " + DIALOG + "...";
		String rfString = NAME + "/createPSOFromAllocation/" + Integer.toString(custID);
		super.doItemUpdate(item, context, dialog, rfString);
	}
	
	/*************************************************************
	 * Code create a new PSO from allocation.
	 *************************************************************/
	public void updateTemplateFromAllocation(final Allocation item, final int templateID, final Context context){
		String dialog = "Updating " + DIALOG + "...";
		String rfString = NAME + "/updateTemplateFromAllocation/" + Integer.toString(templateID);
		super.doItemUpdate(item, context, dialog, rfString);
	}
	
	public void createNewTemplateFromAllocation(final Allocation item, final String templateName, final int repType, final int repCount, final Context context){
		String dialog = "Inserting " + DIALOG + "...";
		String rfString = NAME + "/createNewTemplateFromAllocation/" + templateName + "/" + Integer.toString(repType) + "/" + Integer.toString(repCount);
		doTemplateItemInsertFromAllocation(item, context, dialog, rfString);
	}
	
	public void doTemplateItemInsertFromAllocation(final Allocation item, final Context context, final String dialog, final String str){
		modalDialog = ProgressDialog.show(context, null, dialog);
		final String strStart = URLTools.getURLString(context);
		new InsertItemFromAllocationTask().execute(strStart+str, URLTools.getUSERString(context), URLTools.getPASSString(context), presenter.createJSON(item).toString());
	}
	
	private class InsertItemFromAllocationTask extends AsyncTask<String, Void, String> {
    	@Override
        protected String doInBackground(String... urls) {
            try {
                return RESTfulConnect.postResource(urls[0], urls[1], urls[2], urls[3]);
            } catch (IOException e) {
            	e.printStackTrace();
            	return "Connection Error";
            }
        }
    	@SuppressWarnings("unchecked")
		@Override
        protected void onPostExecute(String result) {
    		try{
    			AllocationTemplatePresenter presenter = new AllocationTemplatePresenter();
	    		modalDialog.dismiss();
	    		ArrayList<AllocationTemplate> items = new ArrayList<AllocationTemplate>();
	    		if(result.subSequence(0, 2).equals("<?")){
	    			AllocationTemplate t = (AllocationTemplate)presenter.tryJSONParse(result);
		    		callback.callback(t, RFAT.INSERT, items);
	    		} else {
	    			JSONObject json = new JSONObject(result);
	    			AllocationTemplate t = (AllocationTemplate)presenter.createItemFromJSONObject(json);
		    		callback.callback(t, RFAT.INSERT, items);
	    		}
    		} catch(JSONException ex){
    			ex.printStackTrace();
    		} 
        }
    }
}
